/*
 * Copyright (C) 2004, Velocityme Partnership
 * NodeAction.java
 *
 * Created on 12 September 2004, 10:18
 */

package com.velocityme.www.interfaces.nodeactions;

import com.velocityme.entity.GroupAccess;
import com.velocityme.entity.Node;
import com.velocityme.entity.Task;
import com.velocityme.entity.UserAccess;
import com.velocityme.enums.Permission;
import com.velocityme.session.GroupAccessLocal;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.NodeLocal;
import com.velocityme.session.SearchLocal;
import com.velocityme.session.TreeLocal;
import com.velocityme.session.UserAccessLocal;
import com.velocityme.www.actionforms.NodeIdActionForm;
import com.velocityme.www.actionforms.NodeLinkIdActionForm;
import com.velocityme.www.actionforms.PostCommentActionForm;
import com.velocityme.www.actionforms.nodeactionforms.NodeActionForm;
import com.velocityme.www.dto.AccessDTO;
import com.velocityme.www.dto.LinkDTO;
import com.velocityme.www.interfaces.ShowNodeAction;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

/**
 *
 * @author  Robert
 */
public class NodeActions extends DispatchAction {
    
    /** Creates a new instance of NodeAction */
    public NodeActions() {
    }
    
    public ActionForward show(ActionMapping mapping, 
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        String selectedTab = (String)request.getAttribute("selectedTab");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = lookupNodeBean().findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, selectedTab);
        return showNode(mapping, form, request, response);
    }
    
    public ActionForward showNode(ActionMapping mapping, 
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        NodeLocal nodeLocal = lookupNodeBean();
        Node node = nodeLocal.findNode(key, nodeId);
        session.setAttribute("node", node);
        session.setAttribute("nodeHistory", nodeLocal.getHistory(key, node));
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward showChangeLog(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request,
                                       HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = lookupNodeBean().findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, "Change Log");
        session.setAttribute("changeDeltaValues", lookupNodeBean().getChangeDeltas(key, node));
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward showUserAccess(ActionMapping mapping, 
                                       	ActionForm form,
                                       	HttpServletRequest request,
                                       	HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = lookupNodeBean().findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, "User Access");
        Collection<AccessDTO> accessDTOs = new ArrayList<AccessDTO>();
        for (UserAccess userAccess: lookupUserAccessBean().getUserAccessByNode(key, node)) {
            boolean isDeletable = lookupSearchBean().getAssignedPermissions(key, userAccess.getNode()).contains(Permission.USER_ACCESS_DELETE);
            Long userAccessId = userAccess.getId();
            String userName = userAccess.getUser().getName();
            accessDTOs.add(new AccessDTO(isDeletable, userAccessId, userAccess.getNode(), userName, userAccess.getRole()));
        }
        session.setAttribute("userAccessByNode", accessDTOs);
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward showGroupAccess(ActionMapping mapping, 
                                     ActionForm form,
                                     HttpServletRequest request,
                                     HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = lookupNodeBean().findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, "Group Access");
        Collection<AccessDTO> accessDTOs = new ArrayList<AccessDTO>();
        for (GroupAccess groupAccess: lookupGroupAccessBean().getGroupAccessByNode(key, node)) {
            boolean isDeletable = lookupSearchBean().getAssignedPermissions(key, groupAccess.getNode()).contains(Permission.GROUP_ACCESS_DELETE);
            Long groupAccessId = groupAccess.getId();
            String groupName = groupAccess.getGroup().getName();
            accessDTOs.add(new AccessDTO(isDeletable, groupAccessId, groupAccess.getNode(), groupName, groupAccess.getRole()));
        }
        session.setAttribute("groupAccessByNode", accessDTOs);
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward showCreate(ActionMapping mapping, 
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Node node = new Node();
        node.setParentNode(lookupNodeBean().findNode(key, nodeId));
        session.setAttribute("node", node);
        return mapping.findForward("ACTION_EDIT");
    }
    
    public ActionForward showEdit(ActionMapping mapping, 
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        session.setAttribute("node", lookupNodeBean().findNode(key, nodeId));
        return mapping.findForward("ACTION_EDIT");
    }
    
    public ActionForward edit(ActionMapping mapping, 
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId;
        if (request.getParameter("btnSubmit").equals("OK")) {
            Node node = (Node)session.getAttribute("node");
            ((NodeActionForm)form).extractNode(node);
            if (node.getId() != null) {
                lookupNodeBean().editNode(key, node);
            }
            else {
                node = lookupNodeBean().createNode(key, node);
            }
            nodeId = node.getId();
        }
        // Cancel simply displays the original node again
        else {
            nodeId = (Long)session.getAttribute("nodeId");
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }
    
    public ActionForward postComment(ActionMapping mapping, 
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (request.getParameter("btnSubmit").equals("OK")) {
            PostCommentActionForm postCommentAF = (PostCommentActionForm)form;
            String comment = postCommentAF.getComment();
            File file = new File(postCommentAF.getFile().getFileName());
            String contentType = postCommentAF.getFile().getContentType();
            InputStream stream = postCommentAF.getFile().getInputStream();
            lookupNodeBean().postComment(key, nodeId, comment, file, contentType, stream);
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }
    
    public ActionForward delete(ActionMapping mapping,
                                ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        NodeLocal nodeLocal = lookupNodeBean();
        if (request.getParameter("btnSubmit").equals("OK")) {
            Long deleteNodeId = ((NodeIdActionForm)form).getNodeId();
            nodeId = nodeLocal.deleteNode(key, deleteNodeId).getId();
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_SUCCESS");
    }
    
    public ActionForward showNodeLinks(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request,
                                       HttpServletResponse response) throws Exception {
        Long nodeId = (Long)request.getAttribute("nodeId");
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        NodeLocal nodeBean = lookupNodeBean();
        Node node = nodeBean.findNode(key, nodeId);
        ShowNodeAction.setupTreeDisplay(session, node, "Links");
        Collection<LinkDTO> linkDTOs = new ArrayList<LinkDTO>();
        SearchLocal searchLocal = lookupSearchBean();
        Set<Permission> assignedPermissions = searchLocal.getAssignedPermissions(key, node);
        boolean isThisDeletable = assignedPermissions.contains(Permission.NODE_EDIT);
        for (Node otherNode: nodeBean.getLinkedNodes(key, node)) {
            boolean deletable = false;
            if (isThisDeletable) {
                assignedPermissions = searchLocal.getAssignedPermissions(key, otherNode);
                deletable = assignedPermissions.contains(Permission.NODE_EDIT);
            }
            linkDTOs.add(new LinkDTO(deletable, otherNode));
        }
        session.setAttribute("linkDisplayDTOs", linkDTOs);
        if (node instanceof Task) {
            Task task = (Task)node;
            session.setAttribute("dependencyLinkDTOs", TaskActions.getDependencyDTOs(key, assignedPermissions, task, true));
            session.setAttribute("dependantLinkDTOs", TaskActions.getDependencyDTOs(key, assignedPermissions, task, false));
        }
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward linkDeleteCheck(ActionMapping mapping, 
                                         ActionForm form,
                                         HttpServletRequest request,
                                         HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        session.setAttribute("linkValue", form);
        return mapping.findForward("ACTION_LINK_DELETE");
    }
    
    public ActionForward linkDelete(ActionMapping mapping, 
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (request.getParameter("btnSubmit").equals("OK")) {
            Long otherNodeId = ((NodeLinkIdActionForm)form).getNodeLinkId();
            lookupTreeBean().deleteNodeLink(key, nodeId, otherNodeId);
        }
        request.setAttribute("nodeId", nodeId);
        return mapping.findForward("ACTION_LINK_DELETE_SUCCESS");
    }

    private NodeLocal lookupNodeBean() {
        try {
            Context c = new InitialContext();
            return (NodeLocal) c.lookup("java:comp/env/NodeBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private SearchLocal lookupSearchBean() {
        try {
            Context c = new InitialContext();
            return (SearchLocal) c.lookup("java:comp/env/SearchBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private UserAccessLocal lookupUserAccessBean() {
        try {
            Context c = new InitialContext();
            return (UserAccessLocal) c.lookup("java:comp/env/UserAccessBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private GroupAccessLocal lookupGroupAccessBean() {
        try {
            Context c = new InitialContext();
            return (GroupAccessLocal) c.lookup("java:comp/env/GroupAccessBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private TreeLocal lookupTreeBean() {
        try {
            Context c = new InitialContext();
            return (TreeLocal) c.lookup("java:comp/env/TreeBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }
    
}
